Retour à la page d’accueil

Visualisation de données avec ggplot2

Lors de cette séance nous allons apprendre à visualiser des jeux de données tabulaires avec ggplot2.

Pour cette formation, nous allons utiliser une version légèrement modifiée du jeu de données publié par Burghard et al 2015.

Il s’agit d’une expérience de phénotypage de plantes d’Arabidopsis thaliana qui ont poussé dans différentes conditions:

  • A 12°C ou à 22°C
  • Avec une température constante ou qui fluctue dans la journée
  • Avec une période de 8h de jour ou de 16h de jour par cycle de 24h
  • Avec un traitement de froid qui imite l’hiver (vernalisation)

Des plantes de différents génotypes ont été analysées: des mutants et sauvages et des écotypes différents.

Pour chaque plante dans chaque condition plusieurs phénotypes ont été mesurés (voir illustration ci-dessous pour mieux comprendre les termes):

  • Le nombre de jour pour que la tige (qui contient les fleurs) émerge: days to bolt
  • Le nombre de jour pour que la première fleur s’ouvre: days to flower
  • Le nombre de feuilles dans la rosette à la fin de l’expérience: rosette leaf num
  • Le nombre de feuilles caulines à la fin de l’expérience: cauline leaf num
  • La longueur du limbe de la feuille: blade lenght mm
  • La longueur de la feuille (avec le pétiole et le limbe) total leaf length mm

Quels types de graphiques pouvons nous faire avec ggplot2?

Il est possible de représenter les données de différentes manières et ggplot2 offre de nombreuses options de visualisation.

Parmi les plus connues:

Et encore plus. Pour toutes les découvrir, voir cette galerie de graphiques avec ggplot2

Mise en place

Ouvrez avec Rstudio le fichier Script_ggplot_lesson.R qui est dans le répertoire session2_ggplot/materiel.

Lors de cette séance nous allons utiliser plusieurs packages qui contiennent les fonctions dont nous avons besoin:
- tidyverse qui contient plusieurs packages dont ggplot2
- visdat qui permet une représentation rapide des données
- plotly pour faire des graphiques interactifs

Ces packages sont normalement déjà installés. Pour les importer dans votre session, utilisez la fonction library() :

library(tidyverse)
library(visdat)
library(plotly)

Vous devez aussi vous assurer que le répertoire de travail de R est bien le dossier qui contient le matériel de la formation. Le chemin vers ce dossier va être différent en fonction de votre système opérateur.
Pour spécifier le répertoire de travail de R utilisez la fonction setwd():

setwd("~/Desktop/2021_L3_R/session2_ggplot/materiel")

Import et vérification des données

Ouvrez avec Rstudio le fichier Script_ggplot_session.R qui est dans le répertoire session2_ggplot/materiel. Nous allons coder ensemble dans ce script, qui est quasiment vide pour le moment.

La version simplifiée des données est dans le dossier session2_ggplot/data (burghardt_et_al_2015_expt1.txt). Il s’agit de données pour des phénotypes associés au temps nécessaire à des plantes de différents génotypes pour fleurir dans différentes conditions.

Comme notre répertoire de travail est le dossier materiel , nous devons importer les données ainsi:

# Import des données et chargement dans l'objet expt1 
expt1 <- read_tsv("../data/burghardt_et_al_2015_expt1.txt")
## Rows: 957 Columns: 15
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: "\t"
## chr (6): genotype, background, fluctuation, vernalization, bolt.survival, bolt
## dbl (9): plant_nb, temperature, day.length, days.to.bolt, days.to.flower, ro...
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

La fonction read_tsv() imprime un message indiquant quel type de données sont contenues dans les différentes colonnes du fichier.

Dans notre cas, certaines colonnes contiennent des données de type “character” (du texte) et d’autres des données numériques (“double” en présence de décimale, “integer” en absence de décimale).

Pour regarder rapidement les données, tapez le nom de l’objet où sont les données (expt1).

expt1
## # A tibble: 957 × 15
##    plant_nb genotype background temperature fluctuation day.length vernalization
##       <dbl> <chr>    <chr>            <dbl> <chr>            <dbl> <chr>        
##  1        1 Col Ama  Col                 12 Con                 16 NV           
##  2        2 Col Ama  Col                 12 Con                 16 NV           
##  3        3 Col Ama  Col                 12 Con                 16 NV           
##  4        4 Col Ama  Col                 12 Con                 16 NV           
##  5        5 Col Ama  Col                 12 Con                 16 NV           
##  6        6 Col Ama  Col                 12 Con                 16 NV           
##  7        7 Col Ama  Col                 12 Con                 16 NV           
##  8        8 Col Ama  Col                 12 Con                 16 NV           
##  9        1 Col Ama  Col                 12 Con                  8 NV           
## 10        2 Col Ama  Col                 12 Con                  8 NV           
## # ℹ 947 more rows
## # ℹ 8 more variables: bolt.survival <chr>, bolt <chr>, days.to.bolt <dbl>,
## #   days.to.flower <dbl>, rosette.leaf.num <dbl>, cauline.leaf.num <dbl>,
## #   blade.length.mm <dbl>, total.leaf.length.mm <dbl>

Cela va montrer les 10 premières lignes du tableau ainsi que les colonnes qui rentrent dans l’écran.

Combien y a-t-il de lignes et colonnes dans les données?

Une autre option est d’utiliser la fonction View() pour accéder à une table interactive où il est possible de trier et filtrer les données sans modifier l’objet:

View(expt1)
  • La fonction glimpse() permet d’avoir une idée de la structure des données:
glimpse(expt1)
## Rows: 957
## Columns: 15
## $ plant_nb             <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1…
## $ genotype             <chr> "Col Ama", "Col Ama", "Col Ama", "Col Ama", "Col …
## $ background           <chr> "Col", "Col", "Col", "Col", "Col", "Col", "Col", …
## $ temperature          <dbl> 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 1…
## $ fluctuation          <chr> "Con", "Con", "Con", "Con", "Con", "Con", "Con", …
## $ day.length           <dbl> 16, 16, 16, 16, 16, 16, 16, 16, 8, 8, 8, 8, 8, 8,…
## $ vernalization        <chr> "NV", "NV", "NV", "NV", "NV", "NV", "NV", "NV", "…
## $ bolt.survival        <chr> "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y",…
## $ bolt                 <chr> "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y",…
## $ days.to.bolt         <dbl> 28, 29, 31, 31, 32, 33, 34, 35, 69, 72, 76, 79, 8…
## $ days.to.flower       <dbl> 43, 44, 43, 42, 44, 47, 47, 49, 90, 91, 97, 99, 1…
## $ rosette.leaf.num     <dbl> 18, 15, 13, 17, 19, 14, 15, 18, 53, 49, 51, 55, 5…
## $ cauline.leaf.num     <dbl> 6, 5, 4, 5, 4, 4, 3, 5, 6, 5, 6, 9, 6, 9, 8, 10, …
## $ blade.length.mm      <dbl> 12.9, 10.5, 13.2, 14.6, 13.3, 14.7, 13.0, 17.8, 2…
## $ total.leaf.length.mm <dbl> 21.1, 19.1, 23.4, 27.2, 20.4, 25.3, 23.2, 31.3, 3…

Quel est le type des variables dans les données ?

  • dim() indique les dimensions du jeu de données (nombre de lignes et colonnes).
dim(expt1)
## [1] 957  15
  • Pour les données numériques, la fonction summary() permet d’obtenir des stats de base pour chaque colonne.
summary(expt1)
##     plant_nb        genotype          background         temperature   
##  Min.   : 1.000   Length:957         Length:957         Min.   :12.00  
##  1st Qu.: 2.000   Class :character   Class :character   1st Qu.:12.00  
##  Median : 4.000   Mode  :character   Mode  :character   Median :12.00  
##  Mean   : 4.589                                         Mean   :16.98  
##  3rd Qu.: 7.000                                         3rd Qu.:22.00  
##  Max.   :12.000                                         Max.   :22.00  
##                                                                        
##  fluctuation          day.length    vernalization      bolt.survival     
##  Length:957         Min.   : 8.00   Length:957         Length:957        
##  Class :character   1st Qu.: 8.00   Class :character   Class :character  
##  Mode  :character   Median :16.00   Mode  :character   Mode  :character  
##                     Mean   :12.01                                        
##                     3rd Qu.:16.00                                        
##                     Max.   :16.00                                        
##                                                                          
##      bolt            days.to.bolt    days.to.flower   rosette.leaf.num
##  Length:957         Min.   : 15.00   Min.   : 21.00   Min.   :  5.00  
##  Class :character   1st Qu.: 38.00   1st Qu.: 46.00   1st Qu.: 24.00  
##  Mode  :character   Median : 57.00   Median : 66.00   Median : 40.00  
##                     Mean   : 66.04   Mean   : 71.59   Mean   : 39.71  
##                     3rd Qu.: 85.00   3rd Qu.: 92.00   3rd Qu.: 53.00  
##                     Max.   :162.00   Max.   :182.00   Max.   :112.00  
##                                      NA's   :83       NA's   :95      
##  cauline.leaf.num blade.length.mm total.leaf.length.mm
##  Min.   : 1.000   Min.   : 7.10   Min.   : 9.00       
##  1st Qu.: 5.000   1st Qu.:18.00   1st Qu.:29.10       
##  Median : 8.000   Median :20.95   Median :34.60       
##  Mean   : 7.208   Mean   :21.11   Mean   :34.69       
##  3rd Qu.: 9.000   3rd Qu.:24.30   3rd Qu.:40.27       
##  Max.   :17.000   Max.   :59.00   Max.   :66.30       
##  NA's   :96       NA's   :327     NA's   :303

Nous avons déjà utilisé de nombreuses fonctions:

  • install.packages()
  • library()
  • read_tsv()
  • View()
  • glimpse()
  • summary()
  • dim()

Il est bien sûr difficile de ce souvenir du nom de toutes ces fonctions, ce qu’elles font et comment les utiliser. Heureusement, pour nous aider, une aide est disponible dans R en tapant le nom d’une fonction précédé de ?

?summary

Bien sur, une recherche sur internet est aussi une solution très efficace pour trouver de l’aide!

Que fait la fonction head() ?

Comment regarder les dernières lignes de le notre jeu de données? (indice: ?tail)

Inspection visuelle des données

Pour avoir une vue d’ensemble du jeu de données et détecter des problèmes, nous allons utiliser la fonction vis_dat().

vis_dat(expt1)

Quel est le type de données le plus courant dans le jeu de données ? Y a-t-il des problème?

Données manquantes

Le gris dans la figure générée par vis_dat() sont des données manquantes. Plusieurs stratégies peuvent être utilisées:

  • supprimer les lignes qui contiennent des données manquantes (le plus sûr, mais cause une perte de données)
  • ignorer les données manquantes

Pour la formation, nous allons enlever les lignes contenant des données manquantes.

expt1 <- drop_na(expt1)

Combien de lignes nous reste-il?

Plots! Plots! Plots!

Maintenant que nous avons vérifié la qualité de notre jeu de donnée, nous pouvons générer des graphiques afin d’en apprendre plus sur les données générées par l’expérience.

Nous allons utiliser le package R ggplot2, qui utilise le principe de “grammar or graphics”. Il s’agit des briques du graphique. Cette méthode permettant de combiner et superposer différentes couches de briques:

  • data (données)
  • aesthetics
  • objet géométrique (type de graphique)
  • transformations statistiques
  • ajustements positionnels
  • faceting

Les trois premières briques sont essentielles: data, aesthetics et objet géométrique.

  • data - Vos données
  • aesthetics - Ce que l’on veux montrer sur le graphique et qui dépend des données. Par exemple ce qui est en x et y, la couleur, forme, type de ligne, taille, etc… Pour cela nous utilisons la fonction aes().
  • geom_objects - les objets que nous voulons dans le graphique. Un graphique doit avoir au moins un geom_object, et peut en avoir plusieurs. Par exemple:
    • points (geom_point pour des scatter plots, dot plots)
    • lignes (geom_line pour des tendance, séries chronologiques)

Pour plus d’information sur la création de graphique avec ggplot2, voir cette antisèche très utile.

Faire un graphique avec ggplot2

Commençons avec un boxplot: Dessinons le days.to.flower pour les différents génotypes.

La fonction ggplot() permet de commencer le graphique. Il faut aussi indiquer les données à utiliser:

ggplot(expt1)

Mais cela ne produit qu’un canevas gris!

Il nous manque des briques. En l’occurrence nous devons indiquer quelle aesthetics (c’est la terminologie de ggplot2) nous voulons sur ce canevas gris. Nous devons indiquer quelles sont les variables x et y du boxplot.

ggplot(expt1, aes(x = genotype, y = days.to.flower))

ggplot indique maintenant les variables genotype et days.to.flower de nos données sur les axes x et y du graphique.

Mais toujours pas de graphique. C’est parce que nous pas indiqué à ggplot quelle géométrie nous voulons dessiner sur le canevas. Pour faire un boxplot, nous ajoutons au canevas (littéralement avec un +) geom_boxplot():

ggplot(expt1, aes(genotype, days.to.flower)) +
  geom_boxplot()

Exercice 1: Pouvez vous dessiner un violin plot? (indice: ?geom_violin)

BONUS Quel autre type de géométrie pouvez vous utilisez avec des données de ce type (catégories sur l’axe x et chiffres sur l’axe y)? Aide: Utilisez cet arbre de décision pour choisir les géométries appropriées.




Retour à la page d’accueil